package com.example.bicycle.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Redis配置类
 * 提供更好的Redis连接处理和错误恢复
 */
@Slf4j
@Configuration
@ConditionalOnClass(RedisTemplate.class)
public class RedisConfig {

    /**
     * 自定义RedisTemplate配置
     * 只有在Redis可用时才创建
     */
    @Bean
    @ConditionalOnProperty(name = "spring.data.redis.host")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        
        try {
            template.setConnectionFactory(connectionFactory);
            
            // 使用String序列化器作为key的序列化器
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
            
            // 使用Jackson序列化器作为value的序列化器
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
            
            template.afterPropertiesSet();
            
            // 测试连接
            template.getConnectionFactory().getConnection().ping();
            log.info("Redis连接成功！");
            
        } catch (Exception e) {
            log.warn("Redis连接失败，应用将在没有Redis的情况下运行: {}", e.getMessage());
            // 不抛出异常，让应用继续运行
        }
        
        return template;
    }

    /**
     * Redis连接健康检查
     */
    @Bean
    public RedisHealthChecker redisHealthChecker() {
        return new RedisHealthChecker();
    }

    /**
     * Redis健康检查器
     */
    public static class RedisHealthChecker {
        
        public boolean isRedisAvailable(RedisTemplate<String, Object> redisTemplate) {
            try {
                if (redisTemplate == null || redisTemplate.getConnectionFactory() == null) {
                    return false;
                }
                redisTemplate.getConnectionFactory().getConnection().ping();
                return true;
            } catch (Exception e) {
                log.debug("Redis健康检查失败: {}", e.getMessage());
                return false;
            }
        }
    }
}
